package org.wsff.tools.api.gateway.core.monitor;

import lombok.Setter;

import java.io.Serializable;

import org.wsff.tools.api.gateway.core.AbstractGateway;
import org.wsff.tools.api.gateway.core.GatewayContext;
import org.wsff.tools.api.gateway.error.GatewayException;
import org.wsff.tools.api.gateway.model.BaseResponse;

/**
 * 监控网关抽象类
 *
 * @author ryan
 * @version Id: AbstractMonitorGateway.java, v 0.1 2022-02-08 13:59 ryan Exp $$
 */
public abstract class AbstractMonitorGateway<Request extends Serializable, Response extends Serializable> extends AbstractGateway<Request, Response> {

    /** gateway monitor service */
    @Setter
    private GatewayMonitor gatewayMonitor;

    /**
     * Resolve error gateway exception.
     *
     * @param context context
     * @param message the message
     * @param e       the e
     * @return the gateway exception
     */
    @Override
    protected GatewayException resolveError(GatewayContext<Request, Response> context, String message, Exception e) {
        MonitorGatewayContext<Request, Response> monitorCtx = (MonitorGatewayContext<Request, Response>) context;
        GatewayException exception = super.resolveError(context, message, e);
        monitorCtx.setResponse(exception.getErrorCode(), exception.getErrorMessage());
        return exception;
    }

    /**
     * 执行
     *
     * @param context 上下文
     * @return 响应
     * @throws GatewayException 异常
     */
    @Override
    protected Response invoke(GatewayContext<Request, Response> context) throws GatewayException {
        MonitorGatewayContext<Request, Response> monitorCtx = (MonitorGatewayContext<Request, Response>) context;
        try {
            monitorCtx.start();
            Response response = super.invoke(context);
            if (response instanceof BaseResponse) {
                BaseResponse responseDTO = (BaseResponse) response;
                monitorCtx.setResponse(responseDTO.getCode(), responseDTO.getMessage());
            }
            return response;
        } finally {
            monitorCtx.stop();
            // 监控
            monitor(monitorCtx);
        }
    }

    /**
     * 监控
     *
     * @param context 上下文
     */
    protected void monitor(MonitorGatewayContext<Request, Response> context) {
        try {
            GatewayMonitor monitor = getGatewayMonitor();
            if (monitor != null) {
                monitor.monitor(context);
            }
        } catch (Exception ignore) {
        }
    }

    /**
     * 获取网关监控服务实现
     *
     * @return 网关监控服务实现
     */
    protected GatewayMonitor getGatewayMonitor() {
        return gatewayMonitor;
    }

}
